package com.fingard.dsp.bank.directbank;


import com.fingard.FGBiz;
import com.fingard.constant.Format;
import com.fingard.diagnostics.LogHelper;
import com.fingard.dsp.bank.directConfig.*;
import com.fingard.dsp.bank.reqrespobj.PacketType;
import com.fingard.dsp.bank.reqrespobj.ReqRespHeader;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.elecbillquery.ReqB006BillStateQry;
import com.fingard.dsp.bank.reqrespobj.elecbillquery.detail.RetAtsB006BillStateQryDetail;
import com.fingard.dsp.bank.reqrespobj.elecbilltrans.detail.ReqB106BillDiscSubmitDetail;
import com.fingard.dsp.bank.reqrespobj.recrefund.ReqQryRecRefund;
import com.fingard.dsp.bank.reqrespobj.recrefund.RetAtsQryRecRefund;
import com.fingard.dsp.bank.reqrespobj.single.ReqQrySingle;
import com.fingard.dsp.bank.reqrespobj.single.detail.ReqPayRecDetail;
import com.fingard.dsp.bank.reqrespobj.single.detail.RetAtsSglDetail;
import com.fingard.dsp.bank.reqrespobj.unifiedorder.ReqQueryOrder;
import com.fingard.dsp.bank.reqrespobj.unifiedorder.RetAtsQueryOrder;
import com.fingard.dsp.bankset.BankFront;
import com.fingard.dsp.bankset.BankFrontBalance;
import com.fingard.dsp.bankset.BankPayInfo;
import com.fingard.dsp.basicbankdata.ebank.EBankData;
import com.fingard.dsp.basicbankdata.ebank.EBankUtil;
import com.fingard.io.FileHelper;
import com.fingard.luna.framework.boot.core.util.SpringContextHolder;
import com.fingard.text.StringHelper;
import com.fingard.text.UrlHelper;
import com.fingard.util.DateHelper;
import com.fingard.util.TransIDHelper;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlOprHelper;
import com.fingard.xml.XmlTextReader;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import org.apache.commons.lang.SerializationUtils;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.text.ParseException;
import java.util.*;

public class DirectBase {

    protected static TransIDHelper tempTransID = new TransIDHelper(1, 99999);
    private static HashMap<String, BankConfig> hashBankConfig = new HashMap<String, BankConfig>();
    @SuppressWarnings("unused")
    private static HashMap<String, SalaryConfig> hashSalaryConfig = new HashMap<String, SalaryConfig>();
    public ReqRespHeader reqHeader;
    public Boolean isNeedHiddleField = false;
    public StringBuilder sbLog = null;
    public int seqIDInner = 0;
    //public Document portReqDoc = null;
    public BankFront bankFront = null;

    public static void resetBankConfig() {
        hashBankConfig = new HashMap<String, BankConfig>();
    }

    public static void refreshBankConfig(String p_bankCode) {
        HashSet<String> hash = new HashSet<String>();
        hash.add(p_bankCode);
        refreshBankConfig(hash);
    }

    /**
     * 刷新BankCoinfg缓存
     */
    public static String refreshBankConfig(HashSet<String> pHashBankCode) {
        StringBuilder sbLog = new StringBuilder();
        HashMap<String, String> filterMap = new HashMap<String, String>();
        for (Map.Entry<String, BankFrontBalance> eachBalance : FGBiz.dspCenter.bankFrontCenter.hashMapBankFront.entrySet()) {
            for (BankFront eachFront : eachBalance.getValue().listBankFront) {
                if (pHashBankCode.contains(eachFront.bankCode)) {//需要刷新
                    String[] entities = eachFront.corporation.split(",");
                    for (String eachEnt : entities) {
                        String entity = eachEnt.trim();
                        String cfgKey = getBankConfigCahceKey(eachFront.bankCode, eachFront.code, entity);
                        if (filterMap.containsKey(cfgKey)) {
                            continue;
                        }
                        filterMap.put(cfgKey, cfgKey);
                        sbLog.append("线路" + eachFront.bankCode + "，组织" + entity + "，前置" + eachFront.code + "-" + eachFront.name + "，");
                        if (hashBankConfig.containsKey(cfgKey)) {
                            try {
                                BankConfig tmpBankConfig = loadExBankConfig(eachFront.bankCode, eachFront.code, entity);
                                hashBankConfig.put(cfgKey, tmpBankConfig);
                                sbLog.append("config缓存已刷新");
                            } catch (Exception e) {
                                FGBiz.limitMsg.exception("refreshBankConfig", e);
                                sbLog.append("config缓存刷新出现异常：" + LogHelper.getStackTrace(e));
                            }
                        } else {
                            sbLog.append("config刷新操作完成");//（当前尚未缓存config，不需刷新）
                        }
                        sbLog.append("\r\n");
                    }
                }
            }
        }
        Iterator<String> itBk = pHashBankCode.iterator();
        while (itBk.hasNext()) {
            String eachBankCode = itBk.next();
            String[] fileNames = new String[2];
            fileNames[0] = "area.xml";
            fileNames[1] = "branch.xml";
            for (int i = 0; i < fileNames.length; i++) {
                String cfgKey = eachBankCode + "-" + fileNames[i];
                if (hashBankConfig.containsKey(cfgKey)) {
                    BankConfig tmpBankConfig = retrieveBankConfig(eachBankCode, fileNames[i]);
                    hashBankConfig.put(cfgKey, tmpBankConfig);
                    sbLog.append("已刷新线路" + eachBankCode + "配置文件" + fileNames[i] + "的缓存\r\n");
                }
            }
        }
        return sbLog.toString();
    }

    public static String getBankConfigCahceKey(String pBankCode, String pBfCode, String pCorporation) {
        return pBankCode + "-" + pBfCode + "-" + pCorporation + "-" + "config.xml";
    }

    /**
     * 从配置文件加载config，三层文件，覆盖方式
     *
     * @throws Exception
     */
    public static BankConfig loadExBankConfig(String pBankCode, String pBfCode, String pCorporation) throws Exception {
        String joinXml = "";
        String[] cfgFileNames = new String[3];
        cfgFileNames[0] = "config." + pBfCode + "." + pCorporation + ".xml";
        cfgFileNames[1] = "config." + pBfCode + ".xml";
        cfgFileNames[2] = "config.xml";
        for (int i = 0; i < cfgFileNames.length; i++) {
            String tmpCfgFilePath = getConfigFilePath(pBankCode, cfgFileNames[i]);
            File tmpFile = new File(tmpCfgFilePath);
            if (tmpFile.exists()) {
                String strXml = FileHelper.readToString(tmpFile, "utf-8");
                joinXml = XmlOprHelper.joinXml(joinXml, strXml, "config");
            }
        }
        BankConfig retBankConfig = new BankConfig();
        if (StringHelper.hasAnyChar(joinXml)) {
            retBankConfig.fromXmlStr(joinXml);
        }
        return retBankConfig;
    }

    protected static BankConfig retrieveBankConfig(String p_bankCode, String p_fileName) {
        if (p_bankCode.startsWith("FnGrd")) {
            p_bankCode = "FnGrd01";
        }
        String tmpCfgFilePath = getConfigFilePath(p_bankCode, p_fileName);
        BankConfig retBankConfig = new BankConfig(tmpCfgFilePath);
        return retBankConfig;
    }

    private static String getConfigFilePath(String p_bankCode, String p_fileName) {
        String cfgPath = FGBiz.dspCenter.rootDirPath + File.separator + "config" + File.separator + "portfiles" + File.separator + p_bankCode + File.separator + p_fileName;//"config.xml"
        return cfgPath;
    }

    protected static String pickupAbstr(String... p_values) {
        boolean isD = false;//纯数字
        boolean isDL = false;//数字和字母的组合
        String prefix = FGBiz.dspCenter.dspSet.abstrPrefix;
        if (FGBiz.dspCenter.dspSet.abstrFormat != null && FGBiz.dspCenter.dspSet.abstrFormat.startsWith("dl")) {
            isDL = true;
        } else if (FGBiz.dspCenter.dspSet.abstrFormat != null && FGBiz.dspCenter.dspSet.abstrFormat.startsWith("d")) {
            isD = true;
        }
        for (int i = 0; i < p_values.length; i++) {
            if (p_values[i] != null && p_values[i].length() > 0) {
                String tmpRet = "";
                if (isDL) {
                    tmpRet = pickupAbstrForDigitAndLetterFormat(p_values[i], FGBiz.dspCenter.dspSet.abstrFormatLen, prefix);
                } else if (isD) {
                    tmpRet = pickupAbstrForDigitFormat(p_values[i], FGBiz.dspCenter.dspSet.abstrFormatLen, prefix);
                } else {
                    tmpRet = pickupAbstrForATS6(p_values[i], prefix);
                }
                if (tmpRet != null && tmpRet.length() > 0) {
                    return tmpRet;
                }
            }
        }
        return "";
    }

    protected static String pickupAbstrForDigitAndLetterFormat(String p_str, int p_len, String prefix) {
        char tmpPreviousType = ' ';
        for (int i = 0; i < p_str.length(); i++) {
            char tmpNowType = ' ';
            char tmpCharNow = p_str.charAt(i);
            if ((tmpCharNow >= 48 && tmpCharNow <= 57) || (tmpCharNow >= 65 && tmpCharNow <= 90) || (tmpCharNow >= 97 && tmpCharNow <= 122)) {
                tmpNowType = 'd';
            } else {
                tmpNowType = 'n';
            }

            if (tmpNowType == 'd' && tmpPreviousType != 'd')//前一位不是数字
            {
                if (i <= p_str.length() - p_len) {
                    boolean tmpIsMatch = true;
                    for (int j = 1; j <= p_len - 1; j++) {
                        if (p_str.charAt(i + j) < 48 || p_str.charAt(i + j) > 122 || (p_str.charAt(i + j) < 65 && p_str.charAt(i + j) > 57) || (p_str.charAt(i + j) < 97 && p_str.charAt(i + j) > 90))//后面p_len-1位全是数字
                        {
                            tmpIsMatch = false;
                            break;
                        }
                    }
                    if (tmpIsMatch) {
                        if (i <= p_str.length() - p_len - 1)//判断第p_len+1位
                        {
                            if (p_str.charAt(i + p_len) < 48 || p_str.charAt(i + p_len) > 122 || (p_str.charAt(i + p_len) < 65 && p_str.charAt(i + p_len) > 57) || (p_str.charAt(i + p_len) < 97 && p_str.charAt(i + p_len) > 90)) {
                                String end = p_str.substring(i, i + p_len);
                                if (end.startsWith(prefix)) {
                                    return end;
                                } else {
                                    tmpPreviousType = tmpNowType;
                                    continue;
                                }
                            }
                        } else {
                            return p_str.substring(i, i + p_len);
                        }
                    }
                } else {
                    return "";
                }
            }
            tmpPreviousType = tmpNowType;
        }
        return "";
    }

    protected static String pickupAbstrForDigitFormat(String p_str, int p_len, String prefix) {
        char tmpPreviousType = ' ';
        for (int i = 0; i < p_str.length(); i++) {
            char tmpNowType = ' ';
            char tmpCharNow = p_str.charAt(i);
            if (tmpCharNow >= 48 && tmpCharNow <= 57) {
                tmpNowType = 'd';
            } else {
                tmpNowType = 'n';
            }

            if (tmpNowType == 'd' && tmpPreviousType != 'd')//前一位不是数字
            {
                if (i <= p_str.length() - p_len) {
                    boolean tmpIsMatch = true;
                    for (int j = 1; j <= p_len - 1; j++) {
                        if (p_str.charAt(i + j) < 48 || p_str.charAt(i + j) > 57)//后面p_len-1位全是数字
                        {
                            tmpIsMatch = false;
                            break;
                        }
                    }
                    if (tmpIsMatch) {
                        if (i <= p_str.length() - p_len - 1)//判断第p_len+1位
                        {
                            if (p_str.charAt(i + p_len) < 48 || p_str.charAt(i + p_len) > 57) {
                                String abstr = p_str.substring(i, i + p_len);
                                if (abstr.startsWith(prefix)) {
                                    return abstr;
                                } else {
                                    tmpPreviousType = tmpNowType;
                                    continue;
                                }
                            }
                        } else {
                            return p_str.substring(i, i + p_len);
                        }
                    }
                } else {
                    return "";
                }
            }
            tmpPreviousType = tmpNowType;
        }
        return "";
    }

    protected static String pickupAbstrForATS6(String p_str, String prefix) {
        char tmpPreviousType = ' ';
        for (int i = 0; i < p_str.length(); i++) {
            char tmpNowType = ' ';
            char tmpCharNow = p_str.charAt(i);
            if (tmpCharNow >= 48 && tmpCharNow <= 57) {
                tmpNowType = 'd';
            } else {
                tmpNowType = 'n';
            }

            if ((tmpCharNow == 51 || tmpCharNow == 50) && tmpPreviousType != 'd')//3，前一位不是数字
            {
                if (i <= p_str.length() - 14) {
                    boolean tmpIsMatch = true;
                    for (int j = 1; j <= 13; j++) {
                        if (p_str.charAt(i + j) < 48 || p_str.charAt(i + j) > 57)//3后面13位全是数字
                        {
                            tmpIsMatch = false;
                            break;
                        }
                    }
                    if (tmpIsMatch) {
                        if (i <= p_str.length() - 15)//判断第15位
                        {
                            if (p_str.charAt(i + 14) < 48 || p_str.charAt(i + 14) > 57) {
                                String abstr = p_str.substring(i, i + 14);
                                if (abstr.startsWith(prefix)) {
                                    return abstr;
                                } else {
                                    tmpPreviousType = tmpNowType;
                                    continue;
                                }
                            }
                        } else {
                            return p_str.substring(i, i + 14);
                        }
                    }
                } else {
                    return "";
                }
            }
            tmpPreviousType = tmpNowType;
        }
        return "";
    }

    /**
     * 返回reqHeader.bankCode+"."+reqHeader.transType，用于日志输出
     */
    public String getLogCode() {
        if (reqHeader != null) {
            return reqHeader.bankCode + "." + reqHeader.transType;
        }
        return "DirectBase";
    }

    public StringBuilder getSbLog() {
        return sbLog;
    }

    public void setSbLog(StringBuilder sb) {
        sbLog = sb;
    }

    /**
     * 渠道主配置config.xml
     *
     * @throws Exception
     */
    public BankConfig getBankConfig() {
        try {
            return DirectBase.getBankConfig(bankFront, reqHeader);
        } catch (Exception e) {
            this.WriteBankLogLn(e);
            return new BankConfig();
        }
    }

    public static BankConfig getBankConfig(BankFront pBankFront, ReqRespHeader pHeader) throws Exception {
        String bfCode = "";
        if (pBankFront != null) {
            bfCode = pBankFront.code;
        }
        String bankCode = pHeader.bankCode;
        if (bankCode.startsWith("FnGrd")) {
            bankCode = "FnGrd01";
        }

        String cfgKey = getBankConfigCahceKey(bankCode, bfCode, pHeader.corporation);

        if (!hashBankConfig.containsKey(cfgKey)) {
            BankConfig tmpBankConfig = loadExBankConfig(bankCode, bfCode, pHeader.corporation);
            synchronized (hashBankConfig) {
                hashBankConfig.put(cfgKey, tmpBankConfig);
            }
        }
        return hashBankConfig.get(cfgKey);
    }

    /**
     * 渠道区域映射配置
     */
    public BankConfig getBankAreaConfig() {
        String cfgKey = reqHeader.bankCode + "-" + "area.xml";
        if (!hashBankConfig.containsKey(cfgKey)) {
            BankConfig tmpBankConfig = retrieveBankConfig(reqHeader.bankCode, "area.xml");
            hashBankConfig.put(cfgKey, tmpBankConfig);
        }
        return hashBankConfig.get(cfgKey);
    }

    /**
     * 电子回单映射配置
     */
    public BankConfig getBankReceiptConfig() {
        String cfgKey = reqHeader.bankCode + "-" + "receipt.xml";
        if (!hashBankConfig.containsKey(cfgKey)) {
            BankConfig tmpBankConfig = retrieveBankConfig(reqHeader.bankCode, "receipt.xml");
            hashBankConfig.put(cfgKey, tmpBankConfig);
        }
        return hashBankConfig.get(cfgKey);
    }

    /**
     * 电票网点映射配置
     */
    public BankConfig getElecBillBranchConfig() {
        String cfgKey = reqHeader.bankCode + "-" + "branch.xml";
        if (!hashBankConfig.containsKey(cfgKey)) {
            BankConfig tmpBankConfig = retrieveBankConfig(reqHeader.bankCode, "branch.xml");
            hashBankConfig.put(cfgKey, tmpBankConfig);
        }
        return hashBankConfig.get(cfgKey);
    }

    /**
     * 设置秒，返回毫秒
     */
    public int getReadTimeout() {
        return getReadTimeout(100);
    }

    /**
     * 设置秒，返回毫秒
     */
    public int getReadTimeout(int p_defSec) {
        return getReadTimeoutSec(p_defSec) * 1000;
    }

    /**
     * 设置秒，返回秒
     */
    public int getReadTimeoutSec(int p_defSec) {
        //秒
        String sec = this.getBankConfig().getSetValue("readTimeout", "" + p_defSec, reqHeader.transType);
        int timeout = p_defSec;
        try {
            timeout = Integer.parseInt(sec);
        } catch (Exception ex) {
            this.WriteBankLogLn(ex);
        }
        return timeout;
    }

    /**
     * 设置秒，返回秒
     */
    public int getReadTimeoutSec(String timeoutType, int p_defSec) {
        //秒
        String sec = this.getBankConfig().getSetValue("readTimeout", "" + p_defSec, timeoutType);
        int timeout = p_defSec;
        try {
            timeout = Integer.parseInt(sec);
        } catch (Exception ex) {
            this.WriteBankLogLn(ex);
        }
        return timeout;
    }

    /**
     * 获取本地存储的数据文件目录，该目录用于保存提交银行或银行返回的数据文件
     *
     * @return 示例：D:\dsp\datafile\yyyyMM\dd\ABC01
     */
    public String getDataFileDirectory(Date p_date) {
        String tmpByDate = Format.Date8Format.format(p_date);
        tmpByDate = tmpByDate.substring(0, 6) + File.separator + tmpByDate.substring(6, 8);
        return FGBiz.dspCenter.dspSet.dataDirPath + File.separator + "datafile" + File.separator + tmpByDate + File.separator + bankFront.code;
    }

    public String getCommonDataFileDirectory(Date p_date, String dir) {
        String tmpByDate = Format.Date8Format.format(p_date);
        tmpByDate = tmpByDate.substring(0, 6) + File.separator + tmpByDate.substring(6, 8);
        return FGBiz.dspCenter.dspSet.dataDirPath + File.separator + "datafile" + File.separator + tmpByDate + File.separator + dir;
    }

    public String getDataIndexDir(Date p_paySentDate) {//不加bankFront.code，因为查询前不知道是哪个前置机，加bankCode
        String tmpByDateHour = Format.DateAndHourFormat.format(p_paySentDate);
        tmpByDateHour = tmpByDateHour.substring(0, 6) + File.separator + tmpByDateHour.substring(6, 8) + File.separator + tmpByDateHour.substring(8, 10) + reqHeader.bankCode;
        return FGBiz.dspCenter.dspSet.dataDirPath + File.separator + "dataindex" + File.separator + tmpByDateHour;
    }

    public String getTempFileDirectory() {
        String tmpByDate = Format.Date8Format.format(new Date());
        tmpByDate = tmpByDate.substring(0, 6) + File.separator + tmpByDate.substring(6, 8);
        return FGBiz.dspCenter.dspSet.dataDirPath + File.separator + "tempfile" + File.separator + tmpByDate + File.separator + reqHeader.bankCode;
    }

    public String getTempFileDirectory(String srcBankCode) {
        String tmpByDate = Format.Date8Format.format(new Date());
        tmpByDate = tmpByDate.substring(0, 6) + File.separator + tmpByDate.substring(6, 8);
        return FGBiz.dspCenter.dspSet.dataDirPath + File.separator + "tempfile" + File.separator + tmpByDate + File.separator + srcBankCode;
    }

    /**
     * 取相对路径，即去掉路径前面的FGBiz.dspCenter.dspSet.dataDirPath + File.separator
     */
    public String getRelativeDataDirPath(String pPath) {
        if (pPath.startsWith(FGBiz.dspCenter.dspSet.dataDirPath)) {
            String retPath = pPath.substring(FGBiz.dspCenter.dspSet.dataDirPath.length());
            return StringHelper.trimStartFileSp(retPath);
        }
        return pPath;
    }

    public String getTempFileDirectory(Date tmpDate) {
        String tmpByDate = Format.Date8Format.format(tmpDate);
        tmpByDate = tmpByDate.substring(0, 6) + File.separator + tmpByDate.substring(6, 8);
        return FGBiz.dspCenter.dspSet.dataDirPath + File.separator + "tempfile" + File.separator + tmpByDate + File.separator + reqHeader.bankCode;
    }

    public String createTempFileDirectory() {
        String tmpByDate = Format.Date8Format.format(new Date());
        tmpByDate = tmpByDate.substring(0, 6) + File.separator + tmpByDate.substring(6, 8);
        String dir = FGBiz.dspCenter.dspSet.dataDirPath + File.separator + "tempfile" + File.separator + tmpByDate + File.separator + reqHeader.bankCode;
        File mdDir = new File(dir);
        if (!mdDir.exists()) {
            mdDir.mkdirs();
        }
        return dir;
    }

    public String createTempFileDirectory(String tmpDate) {
        String tmpByDate = tmpDate;
        tmpByDate = tmpByDate.substring(0, 6) + File.separator + tmpByDate.substring(6, 8);
        String dir = FGBiz.dspCenter.dspSet.dataDirPath + File.separator + "tempfile" + File.separator + tmpByDate + File.separator + reqHeader.bankCode;
        File mdDir = new File(dir);
        if (!mdDir.exists()) {
            mdDir.mkdirs();
        }
        return dir;
    }

    public String createTempFileDirectory(Date tmpDate) {
        String tmpByDate = Format.Date8Format.format(tmpDate);
        tmpByDate = tmpByDate.substring(0, 6) + File.separator + tmpByDate.substring(6, 8);
        String dir = FGBiz.dspCenter.dspSet.dataDirPath + File.separator + "tempfile" + File.separator + tmpByDate + File.separator + reqHeader.bankCode;
        File mdDir = new File(dir);
        if (!mdDir.exists()) {
            mdDir.mkdirs();
        }
        return dir;
    }

    public String getRefundFileDirectory() {
        String tmpByDate = Format.Date8Format.format(new Date());
        tmpByDate = tmpByDate.substring(0, 6) + File.separator + tmpByDate.substring(6, 8);
        return FGBiz.dspCenter.dspSet.dataDirPath + File.separator + "refund" + File.separator + tmpByDate + File.separator + reqHeader.bankCode;
    }

    public String createRefundFileDirectory() {
        String tmpByDate = Format.Date8Format.format(new Date());
        tmpByDate = tmpByDate.substring(0, 6) + File.separator + tmpByDate.substring(6, 8);
        String dir = FGBiz.dspCenter.dspSet.dataDirPath + File.separator + "refund" + File.separator + tmpByDate + File.separator + reqHeader.bankCode;
        File mdDir = new File(dir);
        if (!mdDir.exists()) {
            mdDir.mkdirs();
        }
        return dir;
    }

    public String getPrepareDataDirectory() {
        String tmpByDate = Format.Date8Format.format(new Date());
        tmpByDate = tmpByDate.substring(0, 6) + File.separator + tmpByDate.substring(6, 8);
        return FGBiz.dspCenter.dspSet.dataDirPath + File.separator + "PrepareData" + File.separator + tmpByDate + File.separator + reqHeader.bankCode;
    }

    public String createPrepareDataDirectory() {
        String tmpByDate = Format.Date8Format.format(new Date());
        tmpByDate = tmpByDate.substring(0, 6) + File.separator + tmpByDate.substring(6, 8);
        String dir = FGBiz.dspCenter.dspSet.dataDirPath + File.separator + "PrepareData" + File.separator + tmpByDate + File.separator + reqHeader.bankCode;
        File mdDir = new File(dir);
        if (!mdDir.exists()) {
            mdDir.mkdirs();
        }
        return dir;
    }

    public String getENDIIMPTDirectory() {
        String tmpByDate = Format.Date8Format.format(new Date());
        tmpByDate = tmpByDate.substring(0, 6) + File.separator + tmpByDate.substring(6, 8);
        return FGBiz.dspCenter.dspSet.dataDirPath + File.separator + "ENDIIMPT" + File.separator + tmpByDate + File.separator + reqHeader.bankCode;
    }

    public String createENDIIMPTDirectory() {
        String tmpByDate = Format.Date8Format.format(new Date());
        tmpByDate = tmpByDate.substring(0, 6) + File.separator + tmpByDate.substring(6, 8);
        String dir = FGBiz.dspCenter.dspSet.dataDirPath + File.separator + "ENDIIMPT" + File.separator + tmpByDate + File.separator + reqHeader.bankCode;
        File mdDir = new File(dir);
        if (!mdDir.exists()) {
            mdDir.mkdirs();
        }
        return dir;
    }

    public String getNotifyDataDirectory() {
        String tmpByDate = Format.Date8Format.format(new Date());
        tmpByDate = tmpByDate.substring(0, 6) + File.separator + tmpByDate.substring(6, 8);
        return FGBiz.dspCenter.dspSet.dataDirPath + File.separator + "NotifyData" + File.separator + tmpByDate + File.separator + reqHeader.bankCode;
    }

    public String getNotifyDataDirectory(String date) {
        date = date.substring(0, 6) + File.separator + date.substring(6, 8);
        return FGBiz.dspCenter.dspSet.dataDirPath + File.separator + "NotifyData" + File.separator + date + File.separator + reqHeader.bankCode;
    }

    public String createNotifyDataDirectory() {
        String tmpByDate = Format.Date8Format.format(new Date());
        tmpByDate = tmpByDate.substring(0, 6) + File.separator + tmpByDate.substring(6, 8);
        String dir = FGBiz.dspCenter.dspSet.dataDirPath + File.separator + "NotifyData" + File.separator + tmpByDate + File.separator + reqHeader.bankCode;
        File mdDir = new File(dir);
        if (!mdDir.exists()) {
            mdDir.mkdirs();
        }
        return dir;
    }

    public String createNotifyDataDirectory(String date) {
        date = date.substring(0, 6) + File.separator + date.substring(6, 8);
        String dir = FGBiz.dspCenter.dspSet.dataDirPath + File.separator + "NotifyData" + File.separator + date + File.separator + reqHeader.bankCode;
        File mdDir = new File(dir);
        if (!mdDir.exists()) {
            mdDir.mkdirs();
        }
        return dir;
    }

    public String getCfgDirectory() {
        return FGBiz.dspCenter.dataDirPath + File.separator + "config" + File.separator + "portfiles" + File.separator + reqHeader.bankCode;
    }


    protected Date logFlushTime = null;

    public void setLogFlushTime(Date pTime) {
        logFlushTime = pTime;
    }

    protected void flushBankLog() {
        //writeBankLog(int p_logID, Date p_sTime, Date p_eTime, String prefix, ReqRespHeader p_header, StringBuilder p_sbLog)
        if (sbLog.length() >= 512000) {//512k先输出
            if (logFlushTime == null) {
                logFlushTime = new Date();
            }
            try {
                LogHelper.writeBankLog(this.seqIDInner, logFlushTime, logFlushTime, "", this.reqHeader, sbLog);
                sbLog = sbLog.delete(0, sbLog.length());
            } catch (Exception e) {
                FGBiz.limitMsg.exception("flushBankLog", e);
            }
        }
    }

    protected void WriteBankLogLn(Exception ex) {
        sbLog.append(Format.DateTimeSSSFormat.format(new Date()) + " " + ex.getMessage() + "\r\nStackTrace:\r\n" + LogHelper.getStackTrace(ex) + "\r\n");
        if (reqHeader != null) {
            FGBiz.limitMsg.exception(reqHeader.bankCode + "." + reqHeader.transType, ex);
        } else {
            FGBiz.limitMsg.exception("other", ex);
        }
        flushBankLog();
    }

    public void WriteBankLogLn(Throwable e, String... p_values) {//异常等级8
        sbLog.append(Format.DateTimeSSSFormat.format(new Date()) + " ");
        if (p_values != null) {
            for (int i = 0; i < p_values.length; i++) {
                if (i > 0) {
                    sbLog.append("\t");
                }
                sbLog.append(p_values[i]);
            }
            sbLog.append("\r\n");
        }
        sbLog.append(Format.DateTimeSSSFormat.format(new Date()) + " " + e.getMessage() + "\r\nStackTrace:\r\n" + LogHelper.getStackTrace(e) + "\r\n");
        if (reqHeader != null) {
            FGBiz.limitMsg.exception(reqHeader.bankCode + "." + reqHeader.transType, e, StringHelper.join("\t", p_values));
        } else {
            FGBiz.limitMsg.exception("other", e, StringHelper.join("\t", p_values));
        }
        flushBankLog();
    }

    public void WriteBankLogLn(Throwable ex) {
        sbLog.append(Format.DateTimeSSSFormat.format(new Date()) + " " + ex.getMessage() + "\r\nStackTrace:\r\n" + LogHelper.getStackTrace(ex) + "\r\n");
        if (reqHeader != null) {
            FGBiz.limitMsg.exception(reqHeader.bankCode + "." + reqHeader.transType, ex);
        } else {
            FGBiz.limitMsg.exception("other", ex);
        }
        flushBankLog();
    }

    public void WriteBankLogLn(String strlog) {
        sbLog.append(Format.DateTimeSSSFormat.format(new Date()) + " " + strlog + "\r\n");
        flushBankLog();
    }

    protected void WriteBankLogLn(String strlog, Exception ex) {
        sbLog.append(Format.DateTimeSSSFormat.format(new Date()) + " " + strlog + "\r\n");
        sbLog.append(Format.DateTimeSSSFormat.format(new Date()) + " " + ex.getMessage() + "\r\nStackTrace:\r\n" + LogHelper.getStackTrace(ex) + "\r\n");
        if (reqHeader != null) {
            FGBiz.limitMsg.exception(reqHeader.bankCode + "." + reqHeader.transType, ex);
        } else {
            FGBiz.limitMsg.exception("other", ex);
        }
        flushBankLog();
    }

    /**
     * 比较重要的信息，同时记录到FGBiz.limitMsg
     */
    protected void WriteBankLogAndLimit(String strlog) {
        sbLog.append(Format.DateTimeSSSFormat.format(new Date()) + " " + strlog + "\r\n");
        if (reqHeader != null) {
            FGBiz.limitMsg.add(reqHeader.bankCode + "." + reqHeader.transType, strlog);
        } else {
            FGBiz.limitMsg.add("other", strlog);
        }
        flushBankLog();
    }

    protected void WriteBankLogLn(StringBuilder p_sb) {
        sbLog.append(Format.DateTimeSSSFormat.format(new Date()) + " " + p_sb.toString() + "\r\n");
        flushBankLog();
    }

    //加两个回车换行
    protected void WriteBankLogLn2(String strlog) {
        sbLog.append(Format.DateTimeSSSFormat.format(new Date()) + " " + strlog + "\r\n\r\n");
        flushBankLog();
    }

    /**
     * 发送银行的地址
     */
    protected void WriteBankUrlLogLn(String strUrl) {
        sbLog.append(Format.DateTimeSSSFormat.format(new Date()) + " 发送银行的地址：\r\n");
        sbLog.append(strUrl);
        sbLog.append("\r\n\r\n");
        flushBankLog();
    }

    /**
     * 2.发送银行的报文
     */
    protected void WriteBankLogStep2(String strlog) {
        sbLog.append(Format.DateTimeSSSFormat.format(new Date()) + " 2.发送银行的报文：\r\n");
        sbLog.append(strlog);
        sbLog.append("\r\n\r\n");
        flushBankLog();
    }

    /**
     * 2.发送银行的报文
     */
    protected void WriteBankLogStep2(StringBuilder p_sb) {
        sbLog.append(Format.DateTimeSSSFormat.format(new Date()) + " 2.发送银行的报文：\r\n");
        sbLog.append(p_sb.toString());
        sbLog.append("\r\n\r\n");
        flushBankLog();
    }

    /**
     * 3.银行返回的报文
     */
    protected void WriteBankLogStep3(String strlog) {
        sbLog.append(Format.DateTimeSSSFormat.format(new Date()) + " 3.银行返回的报文：\r\n");
        sbLog.append(strlog);
        sbLog.append("\r\n\r\n");
        flushBankLog();
    }

    /**
     * 3.银行返回的报文
     */
    protected void WriteBankLogStep3(StringBuilder p_sb) {
        sbLog.append(Format.DateTimeSSSFormat.format(new Date()) + " 3.银行返回的报文：\r\n");
        sbLog.append(p_sb.toString());
        sbLog.append("\r\n\r\n");
        flushBankLog();
    }

    /**
     * 3.银行返回的报文
     */
    protected void WriteBankLogStep3(SendBankRespose p_resp) {
        sbLog.append(Format.DateTimeSSSFormat.format(new Date()) + " 3.银行返回的报文：\r\n");
        if (p_resp.connState.length() > 0) {
            sbLog.append(p_resp.connState);
            sbLog.append("\r\n");
        }
        if (p_resp.sbLog != null) {
            sbLog.append(p_resp.sbLog.toString());
            sbLog.append("\r\n\r\n");
        }
        sbLog.append(p_resp.retMessage);
        sbLog.append("\r\n\r\n");
        flushBankLog();
    }

    protected void WriteBankLogLnNoTime(StringBuilder p_sb) {
        sbLog.append(p_sb.toString());
        sbLog.append("\r\n");
        flushBankLog();
    }

    protected void WriteBankLogLnNoTime(String p_str) {
        sbLog.append(p_str);
        sbLog.append("\r\n");
        flushBankLog();
    }

    protected XmlTextReader loadBankRespXmlReader(String p_BNKReturn, StringBuilder p_SbMsg) {
        if (!StringHelper.isNullOrEmpty(p_BNKReturn)) {
            if (p_BNKReturn.indexOf('<') >= 0) {
                try {
                    //p_BKRetDoc = new XmlDocument();
                    //p_BKRet.LoadXml(p_BNKReturn);

                    //StringReader tmpStrReader = new StringReader(p_BNKReturn);
                    //InputSource inSource = new InputSource(tmpStrReader);

                    //DocumentBuilderFactory tmpFactory = DocumentBuilderFactory.newInstance();
                    //DocumentBuilder tmpDomBuilder = tmpFactory.newDocumentBuilder();
                    //return tmpDomBuilder.parse(inSource);
                    XmlTextReader retReader = new XmlTextReader(p_BNKReturn);
                    return retReader;
                } catch (Exception ex) {
                    p_SbMsg.append("载入XML发生异常：" + ex.getMessage());
                    return null;
                }
            } else {
                p_SbMsg.append(p_BNKReturn);
                return null;
            }
        } else {
            p_SbMsg.append("返回内容为空");
            return null;
        }
    }

    protected String convertCurToBank(String p_curATS) throws Exception {
        return convertCurToBank("", p_curATS);
    }

    /**
     * 不同指令使用不同的币种映射
     *
     * @param transType
     * @param p_curATS
     * @return
     * @throws Exception
     */
    protected String convertCurToBank(String transType, String p_curATS) throws Exception {
        if (StringHelper.hasAnyChar(transType)) {
            return getBankConfig().getMapValueByKey("currencyMapping_" + transType, p_curATS);
        } else {
            return getBankConfig().getMapValueByKey("currencyMapping", p_curATS);
        }
    }

    protected String convertCertTypeToBank(String p_certType) throws Exception {
        return getBankConfig().getMapValueByKey("certTypeMapping", p_certType);
    }

    /**
     * 证件类型映射，卡折标志，本方：1折  2借记卡  3贷记卡  4准贷记卡，映射到对方
     */
    protected String convertCardTypeMapping(String pCardType) throws Exception {
        return getBankConfig().getMapValueByKey("cardTypeMapping", pCardType);
    }

    protected String convertBankToBank(String p_bankCode) throws Exception {
        return getBankConfig().getMapValueByKey("bankMapping", p_bankCode);
    }

    protected String convertAreaToBank(String p_areaCode) throws Exception {
        return getBankAreaConfig().getMapValueByKey("areaMapping", p_areaCode);
    }

    protected String[] convertAreaToBank2(String p_areaCode) throws Exception {
        return getBankAreaConfig().getMapValue2ByKey("areaMapping", p_areaCode);
    }

    protected String convertCountryToBank(String p_countryCode) throws Exception {
        return getBankAreaConfig().getMapValueByKey("countryMapping", p_countryCode);
    }

    protected String convertAccountTypeToBank(String p_actType) throws Exception {
        return getBankConfig().getMapValueByKey("accountTypeMapping", p_actType);
    }

    protected String convertBankCodeAreaMapping(String p_bankCode, String p_areaCode) throws Exception {
        String key = p_bankCode + p_areaCode;
        return getBankConfig().getMapValueByKey("bankCodeAreaMapping", key);
    }

    /**
     * 获取config.xml中节点值fail_code中key和value关系
     * 主要用于获取银行返回信息
     *
     * @param code
     * @return
     * @throws Exception
     */
    protected String convertRespToBank(String code) throws Exception {
        return getBankConfig().getMapValueByKey("fail_code", code);
    }

    protected String convertCurToATS(String p_curBank) throws Exception {
        return getBankConfig().getMapKeyByValue("currencyMapping", p_curBank);
    }

    protected String convertPayTypeToS3(String payType) throws Exception {
        return getBankConfig().getMapValueByKey("payTypeMapping", payType);
    }

    protected String convertBusType(String busType) throws Exception {
        return getBankConfig().getMapValueByKey("busTypeMapping", busType);
    }

    protected String converYuanToFen(String amount) {
        if (StringHelper.isNullOrEmpty(amount)) {
            return "";
        }
        BigDecimal decimal = new BigDecimal(amount).multiply(new BigDecimal(100));
        decimal = decimal.setScale(0, BigDecimal.ROUND_HALF_UP);
        return decimal.toString();
    }

    protected String converFenToYuan(String amount) {
        if (StringHelper.isNullOrEmpty(amount)) {
            return "";
        }
        BigDecimal decimal = new BigDecimal(amount).divide(new BigDecimal(100));
        decimal = decimal.setScale(2, BigDecimal.ROUND_HALF_UP);
        return decimal.toString();
    }

    /**
     * 获取config.xml中节点值
     *
     * @param key 节点名称
     * @return 节点值
     */
    protected String getValueAsString(String key) throws Exception {
        return getBankConfig().getValueAsString(key);
    }

    protected boolean canBeNotExist(ReqQrySingle p_req1944, RetAtsSglDetail p_retDetail) throws ParseException {
        return canBeNotExist(p_req1944, p_retDetail, 35);
    }

    protected boolean canBeNotExist(ReqQrySingle p_req1944, RetAtsSglDetail p_retDetail, int p_defWaitMins) throws ParseException {
        String tmpPayState = "5";
        if (StringHelper.hasAnyChar(p_req1944.payState)) {
            tmpPayState = p_req1944.payState;
        }
        if ("5".equals(tmpPayState) || "8".equals(tmpPayState)) {
            int tmpWaitMins = p_defWaitMins;
            if (this.reqHeader != null && reqHeader.bankCode.equals("ICBC02")) {
                if (tmpWaitMins < 60) {
                    tmpWaitMins = 60;//工行默认设置为60分钟
                }
            }

            String setMins = getBankConfig().getSetValue("notExistWaitMins", "", p_req1944.reqHeader.transType);
            if (StringHelper.hasAnyChar(setMins)) {
                tmpWaitMins = Integer.parseInt(setMins);
            } else if (this.getBankConfig().getValueAsInt("notExistWaitMins") > 0) {
                tmpWaitMins = this.getBankConfig().getValueAsInt("notExistWaitMins");
            }

            double tmpDiffMins = DateHelper.getDifferMins(new Date(), p_req1944.getBgnDateTime());
            if (tmpDiffMins < tmpWaitMins) {
                p_retDetail.respCode = "-1";
                double tmpLeftMin = tmpWaitMins - tmpDiffMins;
                p_retDetail.respInfo = "银行返回记录不存在，请于" + Format.DecimalAmtFormat.format(tmpLeftMin) + "分钟后再次查询";
                p_retDetail.transState = "";
                return false;
            }
        } else if (!"7".equals(tmpPayState)) {
            if (this.getBankConfig().getValueAsString("notExistList").indexOf(p_req1944.askNumber) < 0) {
                p_retDetail.respCode = "-1";
                p_retDetail.respInfo = "银行返回记录不存在，而该笔处于支付中，需要联系技术人员排查原因";
                p_retDetail.transState = "";
                return false;
            }
        }
        return true;
    }

    protected boolean canBeNotExist(ReqQryBatPayRec p_reqQryBat, RetAtsQryBatPayRec p_retAts, int p_defWaitMins) throws ParseException {
        String tmpPayState = "5";
        if (StringHelper.hasAnyChar(p_reqQryBat.payState)) {
            tmpPayState = p_reqQryBat.payState;
        }
        if ("5".equals(tmpPayState) || "8".equals(tmpPayState)) {
            int tmpWaitMins = p_defWaitMins;
            if (this.reqHeader != null && reqHeader.bankCode.equals("ICBC02")) {
                if (tmpWaitMins < 60) {
                    tmpWaitMins = 60;//工行默认设置为60分钟
                }
            }
            String setMins = getBankConfig().getSetValue("notExistWaitMins", "", p_reqQryBat.reqHeader.transType);
            if (StringHelper.hasAnyChar(setMins)) {
                tmpWaitMins = Integer.parseInt(setMins);
            } else if (this.getBankConfig().getValueAsInt("notExistWaitMins") > 0) {
                tmpWaitMins = this.getBankConfig().getValueAsInt("notExistWaitMins");
            }
            double tmpDiffMins = DateHelper.getDifferMins(new Date(), p_reqQryBat.getBgnDateTime());
            if (tmpDiffMins < tmpWaitMins) {
                p_retAts.respCode = "-1";
                double tmpLeftMin = tmpWaitMins - tmpDiffMins;
                p_retAts.respInfo = "银行返回记录不存在，请于" + Format.DecimalAmtFormat.format(tmpLeftMin) + "分钟后再次查询";
                p_retAts.transState = "";
                return false;
            }
        } else if (!"7".equals(tmpPayState)) {
            if (this.getBankConfig().getValueAsString("notExistList").indexOf(p_reqQryBat.reqBatchNO) < 0) {
                p_retAts.respCode = "-1";
                p_retAts.respInfo = "银行返回记录不存在，而该笔处于支付中，需要联系技术人员排查原因";
                p_retAts.transState = "";
                return false;
            }
        }
        return true;
    }

    protected boolean canBeNotExist(ReqQueryOrder p_req, RetAtsQueryOrder retAts, int p_defWaitMins) throws ParseException {
        int tmpWaitMins = p_defWaitMins;
        String setMins = getBankConfig().getSetValue("notExistWaitMins", "", p_req.reqHeader.transType);
        if (StringHelper.hasAnyChar(setMins)) {
            tmpWaitMins = Integer.parseInt(setMins);
        } else if (this.getBankConfig().getValueAsInt("notExistWaitMins") > 0) {
            tmpWaitMins = this.getBankConfig().getValueAsInt("notExistWaitMins");
        }
        double tmpDiffMins = DateHelper.getDifferMins(new Date(), p_req.getBgnDateTime());
        if (tmpDiffMins < tmpWaitMins) {
            retAts.respCode = "-1";
            double tmpLeftMin = tmpWaitMins - tmpDiffMins;
            retAts.respInfo = "银行返回记录不存在，请于" + Format.DecimalAmtFormat.format(tmpLeftMin) + "分钟后再次查询";
            retAts.transState = "";
            return false;
        }
        return true;
    }

    protected boolean canBeNotExist(ReqQryRecRefund p_reqQryRef, RetAtsQryRecRefund retAts, int p_defWaitMins) throws ParseException {
        int tmpWaitMins = p_defWaitMins;
        String setMins = getBankConfig().getSetValue("notExistWaitMins", "", p_reqQryRef.reqHeader.transType);
        if (StringHelper.hasAnyChar(setMins)) {
            tmpWaitMins = Integer.parseInt(setMins);
        } else if (this.getBankConfig().getValueAsInt("notExistWaitMins") > 0) {
            tmpWaitMins = this.getBankConfig().getValueAsInt("notExistWaitMins");
        }
        double tmpDiffMins = DateHelper.getDifferMins(new Date(), Format.DateTimeFormat.parse(p_reqQryRef.refundSentDate));
        if (tmpDiffMins < tmpWaitMins) {
            retAts.respCode = "-1";
            double tmpLeftMin = tmpWaitMins - tmpDiffMins;
            retAts.respInfo = "银行返回记录不存在，请于" + Format.DecimalAmtFormat.format(tmpLeftMin) + "分钟后再次查询";
            return false;
        }
        return true;
    }

    public boolean checkBankPayInfo(PacketType p_pckType, String p_bgnDate, String p_bankFrontID, String p_transType, List<String> p_reqSeqID, StringBuilder p_sb) {
        try {
            BankPayInfo bankPayInfo = SpringContextHolder.getBean(BankPayInfo.class);
            return bankPayInfo.insertPayInfo(p_bgnDate, p_bankFrontID, p_transType, p_reqSeqID, p_pckType == PacketType.PayQuery);
        } catch (Exception ex) {
            p_sb.append(ex.getMessage());
            return false;
        }
    }

    public boolean checkBankPayOverTime(XmlTextReader p_reader, StringBuilder p_sb) throws Exception {
        Date chkDate = null;
        String payState = "";
        if (reqHeader.pckType == PacketType.Pay) {
            String payDate = p_reader.getSimpleText("PayDate");
            String payTime = p_reader.getSimpleText("PayTime");
            chkDate = Format.DateTimeFormat.parse(payDate + " " + payTime);
        } else if (reqHeader.pckType == PacketType.PayQuery) {
            String queryType = p_reader.getSimpleTextNotNull("QueryType");
            if ("ByDate".equalsIgnoreCase(queryType)) {//按日查询不需检测
                return true;
            }
            String reqBgnDate = p_reader.getSimpleText("BgnDate");
            if (StringHelper.isNullOrEmpty(reqBgnDate)) {
                reqBgnDate = p_reader.getSimpleText("PaySentDate");
            }
            if (StringHelper.isNullOrEmpty(reqBgnDate)) {
                p_sb.append("查询指令缺少支付发送时间参数");
                return false;
            }
            //Date bgnDate;

            if (reqBgnDate.length() == 14) {//
                chkDate = Format.DateTime14Format.parse(reqBgnDate);
            } else {
                chkDate = Format.DateTimeFormat.parse(reqBgnDate);
            }

            payState = p_reader.getSimpleTextNotNull("PayState");
        }
        return checkBankPayOverTime(chkDate, payState, p_sb);
    }

    public boolean checkBankPayOverTime(HashMap<String, String> p_hashMap, StringBuilder p_sb) throws Exception {
        Date chkDate = null;
        String payState = "";
        if (reqHeader.pckType == PacketType.Pay) {
            if (p_hashMap.containsKey("PayDate") && p_hashMap.containsKey("PayTime")) {
                String payDate = p_hashMap.get("PayDate");
                String payTime = p_hashMap.get("PayTime");
                chkDate = Format.DateTimeFormat.parse(payDate + " " + payTime);
            } else if (p_hashMap.containsKey("PaySentDate")) {
                chkDate = Format.DateTimeFormat.parse(p_hashMap.get("PaySentDate"));
            } else if (p_hashMap.containsKey("BgnDate")) {
                chkDate = Format.DateTimeFormat.parse(p_hashMap.get("BgnDate"));
            }
        } else if (reqHeader.pckType == PacketType.PayQuery) {
            String reqBgnDate = "";
            if (p_hashMap.containsKey("BgnDate")) {
                reqBgnDate = p_hashMap.get("BgnDate");
            } else if (p_hashMap.containsKey("PaySentDate")) {
                reqBgnDate = p_hashMap.get("PaySentDate");
            }
            if (reqBgnDate.length() == 14) {//
                chkDate = Format.DateTime14Format.parse(reqBgnDate);
            } else if (reqBgnDate.length() == 8) {
                chkDate = Format.Date8Format.parse(reqBgnDate);
            } else if (StringHelper.hasAnyChar(reqBgnDate)) {
                chkDate = Format.DateTimeFormat.parse(reqBgnDate);
            } else {
                return true;//为保持兼容
            }

            if (p_hashMap.containsKey("PayState")) {
                payState = p_hashMap.get("PayState");
            }
        }
        return checkBankPayOverTime(chkDate, payState, p_sb);
    }

    public boolean checkBankPayOverTime(Date p_chkDate, String p_payState, StringBuilder p_sb) throws Exception {

        Date tmpTimeNow = new Date();
        float bankPayOverTime_f = getBankConfig().getValueAsFloat("bankPayOverTime");
        if (bankPayOverTime_f <= 0) {
            bankPayOverTime_f = FGBiz.dspCenter.dspConfig.getValueAsFloat("bankPayOverTime");
        }
        if (bankPayOverTime_f <= 0) {
            bankPayOverTime_f = 180;
        }

        if (reqHeader.pckType == PacketType.Pay) {
            if (FGBiz.dspCenter.dspSet.useDBConn && FGBiz.dspCenter.dspSet.enableBankPayInfo) {
                return true;
            }

            if (reqHeader.isReSend) {//属重发，仅判断日期
                if (DateHelper.compareDay(tmpTimeNow, p_chkDate) != 0) {
                    p_sb.append("指令重发不能跨日");
                    this.WriteBankLogLn(p_sb.toString() + ",timeNow:" + Format.DateTimeSSSFormat.format(tmpTimeNow) + ",chkDate:" + Format.DateTimeSSSFormat.format(p_chkDate));
                    return false;
                }
            } else {
                double diffSecs = DateHelper.getDifferSecs(tmpTimeNow, p_chkDate);
                if (diffSecs > bankPayOverTime_f) {
                    p_sb.append("指令超时" + Format.DecimalAmtFormat.format(diffSecs - bankPayOverTime_f) + "秒");
                    this.WriteBankLogLn(p_sb.toString() + ",timeNow:" + Format.DateTimeSSSFormat.format(tmpTimeNow) + ",chkDate:" + Format.DateTimeSSSFormat.format(p_chkDate));
                    return false;
                } else if (diffSecs < -60) {
                    p_sb.append("指令超前" + Format.DecimalAmtFormat.format(diffSecs + 60) + "秒");
                    this.WriteBankLogLn(p_sb.toString() + ",timeNow:" + Format.DateTimeSSSFormat.format(tmpTimeNow) + ",chkDate:" + Format.DateTimeSSSFormat.format(p_chkDate));
                    return false;
                }
            }
        } else if (reqHeader.pckType == PacketType.PayQuery) {
            float bankPayExpiredDay_f = getBankConfig().getValueAsFloat("bankPayExpiredDay");
            if (bankPayExpiredDay_f <= 0) {
                bankPayExpiredDay_f = FGBiz.dspCenter.dspConfig.getValueAsFloat("bankPayExpiredDay");
            }
            if (bankPayExpiredDay_f <= 0) {
                bankPayExpiredDay_f = 28;
            }

            double diffDays = DateHelper.getDifferDays(tmpTimeNow, p_chkDate);
            if (diffDays > bankPayExpiredDay_f) {
                p_sb.append("支付指令已经过期" + Format.DecimalAmtFormat.format(diffDays - bankPayExpiredDay_f) + "天，不能再进行查询，请联系银行确认状态");
                this.WriteBankLogLn(p_sb.toString() + ",timeNow:" + Format.DateTimeSSSFormat.format(tmpTimeNow) + ",chkDate:" + Format.DateTimeSSSFormat.format(p_chkDate));
                return false;
            }

            //扫码、H5、APP、公众号、网关，这几种查询解除超时判断
            if ("QueryQRPay".equalsIgnoreCase(reqHeader.transType) || "QueryH5Pay".equalsIgnoreCase(reqHeader.transType) || "QueryAPPPay".equalsIgnoreCase(reqHeader.transType) || "QueryJSAPIPay".equalsIgnoreCase(reqHeader.transType) || "QueryGwOrder".equalsIgnoreCase(reqHeader.transType) || "9144".equalsIgnoreCase(reqHeader.transType)) {
                return true;
            }

            float queryOverTime_f = bankPayOverTime_f + 120;

            if (!p_payState.equals("2") && !p_payState.equals("4") && !p_payState.equals("paying") && !p_payState.equals("1") && !p_payState.equals("8")) {
                boolean isExceptionQuery = false;
                float exceptionQueryOverTime_f = getBankConfig().getValueAsFloat("exceptionQueryOverTime");
                if (exceptionQueryOverTime_f < 0) {
                    exceptionQueryOverTime_f = FGBiz.dspCenter.dspConfig.getValueAsFloat("exceptionQueryOverTime");
                }
                if (exceptionQueryOverTime_f > 0) {
                    exceptionQueryOverTime_f = exceptionQueryOverTime_f * 60;//单位分钟，需要转为秒
                    exceptionQueryOverTime_f += queryOverTime_f;
                    if (exceptionQueryOverTime_f > queryOverTime_f) {
                        isExceptionQuery = true;
                        queryOverTime_f = exceptionQueryOverTime_f;
                    }
                }
                double diffQrySecs = DateHelper.getDifferSecs(tmpTimeNow, p_chkDate);
                if (diffQrySecs < queryOverTime_f) {
                    double tmpWaitMin = (queryOverTime_f - diffQrySecs) / 60;
                    if (tmpWaitMin > 1) {
                        if (isExceptionQuery) {
                            p_sb.append("交易处于未知状态，请于" + Format.DecimalAmtFormat.format(tmpWaitMin) + "分钟后再进行查询");
                        } else {
                            p_sb.append("离支付发送时间太近，请于" + Format.DecimalAmtFormat.format(tmpWaitMin) + "分钟后再进行查询");
                        }
                    } else {
                        if (isExceptionQuery) {
                            p_sb.append("交易处于未知状态，请稍后再查询");
                        } else {
                            p_sb.append("离支付发送时间太近，请稍后再查询");
                        }
                    }
                    this.WriteBankLogLn(p_sb.toString() + ",timeNow:" + Format.DateTimeSSSFormat.format(tmpTimeNow) + ",chkDate:" + Format.DateTimeSSSFormat.format(p_chkDate));
                    return false;
                }
            }
        }
        return true;
    }

    protected void nodeAnalysis(XElement p_srcXE, HashMap<String, String> p_trgHash, String p_charset) throws UnsupportedEncodingException {
        XElement trgXE = new XElement("a", "");
        Iterator<String> iter = p_trgHash.keySet().iterator();
        while (iter.hasNext()) {
            String eachKey = iter.next();
            trgXE.addChild(new XElement(eachKey, p_trgHash.get(eachKey)));
        }
        nodeAnalysis(p_srcXE, trgXE, p_charset);
        ArrayList<XElement> listEach = trgXE.getAllChildList();
        for (int i = 0; i < listEach.size(); i++) {
            if (p_trgHash.containsKey(listEach.get(i).name)) {
                if (!listEach.get(i).innerText.equals(p_trgHash.get(listEach.get(i).name))) {
                    p_trgHash.put(listEach.get(i).name, listEach.get(i).innerText);
                }
            }

        }
    }

    protected void nodeAnalysis(XElement p_srcXE, XElement p_trgXE, String p_charset) throws UnsupportedEncodingException {
        if (reqHeader != null) {

            EBankSet eBankSet = getBankConfig().getEBankSet(reqHeader.commandCode, reqHeader.transType);
            if (eBankSet != null) {
                XElement tmpSrcXe = p_srcXE;
                EBankUtil.setEBankInfo(reqHeader.commandCode, tmpSrcXe, p_trgXE, eBankSet, getSbLog());
            }

            NodeAnalysisSet nodeSet = getBankConfig().getNodeAnalysisSet(reqHeader.commandCode, reqHeader.transType, "*");
            if (nodeSet != null) {
                Iterator<NodeAnalysisItem> items = nodeSet.items.iterator();
                while (items.hasNext()) {
                    NodeAnalysisItem eachItem = items.next();
                    boolean matchCondition = true;
                    if (StringHelper.hasAnyChar(eachItem.condition)) {//condition="ownBank:102"
                        String[] conds = eachItem.condition.split(",");
                        for (int i = 0; i < conds.length; i++) {
                            String[] eachCd = conds[i].split(":");
                            if (eachCd.length == 2) {
                                if ("ownBank".equalsIgnoreCase(eachCd[0])) {
                                    if (!eachCd[1].equalsIgnoreCase(reqHeader.syBank)) {
                                        matchCondition = false;
                                        break;
                                    }
                                } else if ("ownAct".equalsIgnoreCase(eachCd[0])) {
                                    if (!eachCd[1].equalsIgnoreCase(reqHeader.ownAct)) {
                                        matchCondition = false;
                                        break;
                                    }
                                } else {
                                    matchCondition = false;
                                    break;
                                }
                            } else {
                                matchCondition = false;
                                break;
                            }
                        }
                    }
                    if (!matchCondition) {
                        continue;
                    }
                    if (StringHelper.hasAnyChar(eachItem.src) && StringHelper.hasAnyChar(eachItem.trg)) {
                        String theCharset = "gbk";
                        if (StringHelper.hasAnyChar(eachItem.charset)) {
                            theCharset = eachItem.charset;
                        } else if (StringHelper.hasAnyChar(nodeSet.charset)) {
                            theCharset = nodeSet.charset;
                        } else if (StringHelper.hasAnyChar(p_charset)) {
                            theCharset = p_charset;
                        }

                        String unionSetValue = eachItem.prefix;
                        String[] srcList = eachItem.src.split(",");
                        for (int i = 0; i < srcList.length; i++) {
                            String[] columnList = srcList[i].split("\\|");
                            String eachValue = "";
                            String tmpEachSrcName = "";
                            for (String eachColumn : columnList) {//竖线分隔中取第一个有值的
                                tmpEachSrcName = eachColumn.trim();
                                String tmpSrcNodeName = tmpEachSrcName;
                                XElement tmpNodeSource = null;
                                if (tmpEachSrcName.startsWith("target.")) {
                                    tmpSrcNodeName = StringHelper.trimStart(tmpEachSrcName, "target.");
                                    tmpNodeSource = p_trgXE.getSingleChild(tmpSrcNodeName);
                                    if (tmpNodeSource != null) {
                                        if (StringHelper.hasAnyChar(tmpNodeSource.innerText)) {
                                            eachValue = tmpNodeSource.innerText;
                                        }
                                    } else {
                                        this.WriteBankLogLnNoTime("节点解析配置有误，不存在来源节点" + tmpEachSrcName);
                                    }
                                } else if (tmpSrcNodeName.startsWith("\"") && tmpSrcNodeName.endsWith("\"")) {
                                    String dValue = StringHelper.trimStart(tmpSrcNodeName, "\"");
                                    dValue = StringHelper.trimEnd(dValue, "\"");
                                    eachValue = dValue;
                                } else {
                                    tmpNodeSource = p_srcXE.getSingleChild(tmpSrcNodeName);
                                    if (tmpNodeSource != null) {
                                        eachValue = tmpNodeSource.innerText;
                                    } else {
                                        this.WriteBankLogLnNoTime("节点解析配置有误，不存在来源节点" + tmpEachSrcName);
                                    }
                                }
                                if (StringHelper.hasAnyChar(eachValue)) {
                                    break;//第一个有值就结束本次循环，适用Usage|Memo|Description
                                }
                            }

                            if (StringHelper.hasAnyChar(eachValue)) {
                                /*
                                 * if (_TransType == "1988" || _TransType == "9188")
            {
                tmpSourcePostScript = p_NodeRecord.SelectSingleNode("descendant::").InnerText;//ATS端的对照码内容
            }
            else
            {
                tmpSourcePostScript = p_NodeRecord.SelectSingleNode("descendant::PostScript").InnerText;//ATS端的对照码内容
            }
                            	 * */
                                if (eachItem.intact && eachItem.cut > 0) {
                                    boolean isAbsColumn = false;
                                    if ((reqHeader.transType.equals("1988") || reqHeader.transType.equals("9188")) && tmpEachSrcName.equals("ReqReserve")) {
                                        isAbsColumn = true;
                                    } else if (tmpEachSrcName.equals("PostScript")) {
                                        isAbsColumn = true;
                                    }
                                    if (isAbsColumn) {//是对账码，需要保持完整
                                        int nowLen = unionSetValue.getBytes(theCharset).length;
                                        int addLen = eachValue.getBytes(theCharset).length;
                                        if (StringHelper.hasAnyChar(eachItem.union) && StringHelper.hasAnyChar(unionSetValue)) {
                                            addLen += eachItem.union.getBytes(theCharset).length;
                                        }
                                        int nextLen = nowLen + addLen;
                                        if (nextLen > eachItem.cut) {
                                            int maxNowLen = eachItem.cut - addLen;
                                            if (maxNowLen > 0) {//把前面的截了，保证能装得下对账码
                                                unionSetValue = StringHelper.subStringByByte(unionSetValue, theCharset, maxNowLen);
                                            } else {
                                                unionSetValue = "";
                                            }
                                        }
                                    }
                                }

                                if (StringHelper.hasAnyChar(eachItem.union) && StringHelper.hasAnyChar(unionSetValue) && unionSetValue.length() > eachItem.prefix.length()) {
                                    unionSetValue += eachItem.union;
                                }

                                unionSetValue += eachValue;
                            }
                        }

                        //src为空则取备选节点
                        if (StringHelper.isNullOrEmpty(unionSetValue) && StringHelper.hasAnyChar(eachItem.srcOption)) {
                            String[] srcOptList = eachItem.srcOption.split(",");
                            for (int i = 0; i < srcOptList.length; i++) {
                                String eachValue = "";
                                String tmpEachSrcName = srcOptList[i].trim();
                                String tmpSrcNodeName = tmpEachSrcName;
                                XElement tmpNodeSource = null;
                                if (tmpEachSrcName.startsWith("target.")) {
                                    tmpSrcNodeName = StringHelper.trimStart(tmpEachSrcName, "target.");
                                    tmpNodeSource = p_trgXE.getSingleChild(tmpSrcNodeName);
                                    if (tmpNodeSource != null) {
                                        if (StringHelper.hasAnyChar(tmpNodeSource.innerText)) {
                                            eachValue = tmpNodeSource.innerText;
                                        }
                                    } else {
                                        this.WriteBankLogLnNoTime("节点解析配置有误，不存在来源节点" + tmpEachSrcName);
                                    }
                                } else if (tmpSrcNodeName.startsWith("\"") && tmpSrcNodeName.endsWith("\"")) {
                                    String dValue = StringHelper.trimStart(tmpSrcNodeName, "\"");
                                    dValue = StringHelper.trimEnd(dValue, "\"");
                                    eachValue = dValue;
                                } else {
                                    tmpNodeSource = p_srcXE.getSingleChild(tmpSrcNodeName);
                                    if (tmpNodeSource != null) {
                                        eachValue = tmpNodeSource.innerText;
                                    } else {
                                        this.WriteBankLogLnNoTime("节点解析配置有误，不存在来源节点" + tmpEachSrcName);
                                    }
                                }
                                if (StringHelper.hasAnyChar(eachValue)) {
                                    unionSetValue = eachValue;
                                    break;
                                }
                            }
                        }
                        XElement tmpNodeTarget = p_trgXE.getSingleChild(eachItem.trg);
                        if (tmpNodeTarget != null) {
                            if (StringHelper.hasAnyChar(eachItem.split) && eachItem.index > 0) {
                                String[] unionSetValues = unionSetValue.split(eachItem.split);
                                if (unionSetValues != null && unionSetValues.length >= eachItem.index) {
                                    unionSetValue = unionSetValues[eachItem.index - 1];
                                }
                            }
                            if (eachItem.cut > 0) {
                                unionSetValue = StringHelper.subStringByByte(unionSetValue, theCharset, eachItem.cut);
                            }
                            tmpNodeTarget.innerText = unionSetValue;
                            String tmpNoJoinPostScriptText = FGBiz.dspCenter.dspSet.noJoinPostScriptText;
                            String[] tmpNoJoinStr = tmpNoJoinPostScriptText.split(",");
                            if (tmpNodeTarget.innerText != null && tmpNoJoinPostScriptText.length() > 0) {
                                for (int i = 0; i < tmpNoJoinStr.length; i++) {
                                    String tmpName = p_srcXE.getSingleChild("RecName").innerText;
                                    if (tmpNodeTarget.innerText.contains(tmpNoJoinStr[i]) || tmpName.contains(tmpNoJoinStr[i])) {
                                        tmpNodeTarget.innerText = p_srcXE.getSingleChild("Usage").innerText;
                                        break;
                                    }
                                }
                            }
                        } else {
                            this.WriteBankLogLnNoTime("节点解析配置有误，不存在目标节点" + eachItem.trg);
                        }
                    } else {
                        this.WriteBankLogLnNoTime("节点解析配置有误，目标节点" + eachItem.trg + "和来源节点" + eachItem.src + "都不能为空");
                    }
                }
            }
        }
    }

    protected void nodeAnalysic(Object p_srcXE, Object p_trgObj, String p_charset) throws Exception {
        if (reqHeader != null) {
            NodeAnalysisSet nodeSet = getBankConfig().getNodeAnalysisSet(reqHeader.commandCode, reqHeader.transType, "*");
            if (nodeSet != null) {
                Iterator<NodeAnalysisItem> items = nodeSet.items.iterator();
                while (items.hasNext()) {
                    NodeAnalysisItem eachItem = items.next();
                    if (StringHelper.hasAnyChar(eachItem.src) && StringHelper.hasAnyChar(eachItem.trg)) {
                        String theCharset = "gbk";
                        if (StringHelper.hasAnyChar(eachItem.charset)) {
                            theCharset = eachItem.charset;
                        } else if (StringHelper.hasAnyChar(nodeSet.charset)) {
                            theCharset = nodeSet.charset;
                        } else if (StringHelper.hasAnyChar(p_charset)) {
                            theCharset = p_charset;
                        }

                        String unionSetValue = eachItem.prefix;
                        String[] tmpSrcList = eachItem.src.split(",");
                        for (int i = 0; i < tmpSrcList.length; i++) {
                            String eachValue = "";
                            String tmpEachSrcName = tmpSrcList[i].trim();
                            String tmpSrcNodeName = tmpEachSrcName;
                            if (p_srcXE instanceof XElement) {
                                XElement tmpSrcXe = (XElement) p_srcXE;
                                XElement tmpNodeSource = null;

                                tmpNodeSource = tmpSrcXe.getSingleChild(tmpSrcNodeName);
                                if (tmpNodeSource != null) {
                                    eachValue = tmpNodeSource.innerText;
                                } else {
                                    this.WriteBankLogLnNoTime("节点解析配置有误，不存在来源节点" + tmpEachSrcName);
                                }
                            } else if (p_srcXE instanceof String[]) {
                                String[] tmpSrcXe = (String[]) p_srcXE;
                                try {
                                    int tmpSrcNodeIndex = Integer.parseInt(tmpSrcNodeName);
                                    if (tmpSrcXe.length >= tmpSrcNodeIndex) {
                                        eachValue = tmpSrcXe[tmpSrcNodeIndex];
                                    } else {
                                        this.WriteBankLogLnNoTime("节点解析配置有误，不存在来源节点" + tmpEachSrcName);
                                    }
                                } catch (Exception ex) {
                                    this.WriteBankLogLnNoTime("节点解析配置有误，失败原因：" + ex.getMessage());
                                }
                            }

                            if (StringHelper.hasAnyChar(eachValue)) {
                                if (StringHelper.hasAnyChar(eachItem.split) && eachValue.indexOf(eachItem.split) > 0) {
                                    String[] tmpunionSetValue = eachValue.split("\\" + eachItem.split);
                                    if (tmpunionSetValue != null && tmpunionSetValue.length >= eachItem.index) {
                                        unionSetValue += eachValue.split("\\" + eachItem.split)[eachItem.index - 1];
                                    }
                                } else {
                                    if (StringHelper.hasAnyChar(eachItem.union) && StringHelper.hasAnyChar(unionSetValue) && unionSetValue.length() > eachItem.prefix.length()) {
                                        unionSetValue += eachItem.union;
                                    }

                                    unionSetValue += eachValue;
                                }
                            }
                        }

                        //src为空则取备选节点
                        if (StringHelper.isNullOrEmpty(unionSetValue) && StringHelper.hasAnyChar(eachItem.srcOption)) {
                            String[] srcOptList = eachItem.srcOption.split(",");
                            for (int i = 0; i < srcOptList.length; i++) {
                                String eachValue = "";
                                String tmpEachSrcName = srcOptList[i].trim();
                                String tmpSrcNodeName = tmpEachSrcName;
                                if (p_srcXE instanceof XElement) {
                                    XElement tmpSrcXe = (XElement) p_srcXE;
                                    XElement tmpNodeSource = null;

                                    tmpNodeSource = tmpSrcXe.getSingleChild(tmpSrcNodeName);
                                    if (tmpNodeSource != null) {
                                        eachValue = tmpNodeSource.innerText;
                                    } else {
                                        this.WriteBankLogLnNoTime("节点解析配置有误，不存在来源节点" + tmpEachSrcName);
                                    }
                                } else if (p_srcXE instanceof String[]) {
                                    String[] tmpSrcXe = (String[]) p_srcXE;
                                    try {
                                        int tmpSrcNodeIndex = Integer.parseInt(tmpSrcNodeName);
                                        if (tmpSrcXe.length >= tmpSrcNodeIndex) {
                                            eachValue = tmpSrcXe[tmpSrcNodeIndex];
                                        } else {
                                            this.WriteBankLogLnNoTime("节点解析配置有误，不存在来源节点" + tmpEachSrcName);
                                        }
                                    } catch (Exception ex) {
                                        this.WriteBankLogLnNoTime("节点解析配置有误，失败原因：" + ex.getMessage());
                                    }
                                }

                                if (StringHelper.hasAnyChar(eachValue)) {
                                    unionSetValue = eachValue;
                                    break;
                                }
                            }
                        }


                        if (eachItem.cut > 0) {
                            unionSetValue = StringHelper.subStringByByte(unionSetValue, theCharset, eachItem.cut);
                        }
                        reflectSetObjectAttrValue(p_trgObj, eachItem.trg, unionSetValue);
                    } else {
                        this.WriteBankLogLnNoTime("节点解析配置有误，目标节点" + eachItem.trg + "和来源节点" + eachItem.src + "都不能为空");
                    }

                }
            }
        }
    }

    private void reflectSetObjectAttrValue(Object p_obj, String p_fieldName, String p_fieldValue) throws Exception {
        Field f = null;
        try {
            f = p_obj.getClass().getDeclaredField(p_fieldName);
        } catch (NoSuchFieldException e) {
            this.WriteBankLogLnNoTime("节点解析配置有误，不存在目标节点" + p_fieldName);
        }
        if (f != null) {
            f.setAccessible(true);
            f.set(p_obj, p_fieldValue);
        }
    }

    protected void sendDataToMQ(HashMap<String, String> p_hashMap) {
        Connection connection = null;
        Channel channel = null;

        try {
            NotifySet ntfSet = FGBiz.dspCenter.dspConfig.getNotifySet("auth");
            if ("MQ".equals(ntfSet.notifyType)) {
                StringBuilder sbLogBuilder = new StringBuilder();
                Iterator<String> iter = p_hashMap.keySet().iterator();
                while (iter.hasNext()) {
                    String eachKey = iter.next();
                    sbLogBuilder.append(eachKey + ":" + p_hashMap.get(eachKey) + "\r\n");
                }

                WriteBankLogLn("MQ通知地址：" + ntfSet.notifyHost);
                WriteBankLogLn("MQ通知报文：" + sbLogBuilder.toString());

                ConnectionFactory factory = new ConnectionFactory();

                String[] ipAport = UrlHelper.pickupIpAndPort(ntfSet.notifyHost);
                factory.setHost(ipAport[0]);
                factory.setPort(Integer.parseInt(ipAport[1]));
                factory.setVirtualHost(ntfSet.notifyVirtualHost);
                factory.setUsername(ntfSet.notifyUsername);
                factory.setPassword(ntfSet.notifyPassword);

                connection = factory.newConnection();
                channel = connection.createChannel();
                channel.queueDeclare(ntfSet.getNotifyQueueName("auth"), true, false, false, null);
                channel.basicPublish("", ntfSet.getNotifyQueueName("auth"), null, SerializationUtils.serialize(p_hashMap));
            } else {
                WriteBankLogLn("未配置notifySet，无需主动通知");
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            WriteBankLogLn(ex);
        }
    }

    /**
     * 获取当前日切时间
     *
     * @param tmpDate 当前时间
     * @return 计算后日切时间
     */
    public Date getDayCutTime(Date tmpDate) {
        Date tmpDateNow = tmpDate;

        String dayCutTime = getBankConfig().getValueAsString("dayCutTime");
        if (StringHelper.hasAnyChar(dayCutTime)) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(tmpDate);

            int tmpDayCutTime = Integer.parseInt(dayCutTime.replace(":", ""));
            int tmpTimeNow = calendar.get(Calendar.HOUR_OF_DAY) * 100 + calendar.get(Calendar.MINUTE);
            if (tmpTimeNow >= tmpDayCutTime) {
                calendar.add(Calendar.DATE, 1);
                tmpDateNow = calendar.getTime();
            }
        } else {
            WriteBankLogLn("配置文件缺失:'dayCutTime'配置节点!");
        }

        return tmpDateNow;
    }

    /**
     * 获取当前总笔数
     *
     * @param param
     * @return
     */
    public String getTotalNum(String param) {
        if (StringHelper.isNullOrEmpty(param)) {
            param = "0";
        }
        return param;
    }

    //当交易完成之后由于权利人发生变化，导致票据状态无法查回，需要dsp自己填充
    protected void padBillState(String success, RetAtsB006BillStateQryDetail detail, ReqB006BillStateQry query) {
        if (StringHelper.isNullOrEmpty(detail.billState)) {
            //对方已签收
            if (success.equals(detail.transState)) {
                if ("4".equals(query.detail.operType) && "1".equals(query.detail.busiType)) {  //退票
                    detail.billState = "000002";    //结束已作废
                    WriteBankLogLn("由于银行没有返回票据状态：根据撤票业务和交易成功填充票据状态【000002】结束已作废");
                } else if ("1".equals(query.detail.operType) && "3".equals(query.detail.busiType)) {//提示收票
                    detail.billState = "030006";//提示收票已签收
                    WriteBankLogLn("由于银行没有返回票据状态：根据提示收票业务和交易成功填充票据状态【030006】提示收票已签收");
                } else if ("1".equals(query.detail.operType) && "4".equals(query.detail.busiType)) {//背书转让
                    detail.billState = "100006";//背书已签收
                    WriteBankLogLn("由于银行没有返回票据状态：根据背书转让业务和交易成功填充票据状态【100006】背书已签收");
                } else if ("1".equals(query.detail.operType) && "5".equals(query.detail.busiType)) {//质押申请
                    detail.billState = "180006";//质押已签收
                    WriteBankLogLn("由于银行没有返回票据状态：根据质押业务和交易成功填充票据状态【180006】质押已签收");
                } else if ("1".equals(query.detail.operType) && "6".equals(query.detail.busiType)) {//质押解除申请
                    detail.billState = "190006";//质押解除已签收
                    WriteBankLogLn("由于银行没有返回票据状态：根据质押解除业务和交易成功填充票据状态【190006】质押解除已签收");
                } else if ("1".equals(query.detail.operType) && "10".equals(query.detail.busiType)) {//贴现申请
                    if ("1".equals(query.detail.discType)) { //买断式贴现
                        detail.billState = "110106";//买断式贴现已签收
                        WriteBankLogLn("由于银行没有返回票据状态：根据买断式贴现业务和交易成功填充票据状态【110106】买断式贴现已签收");
                    } else if ("2".equals(query.detail.discType)) { //回购式贴现
                        detail.billState = "110206";//回购式贴现已签收
                        WriteBankLogLn("由于银行没有返回票据状态：根据回购式贴现业务和交易成功填充票据状态【110206】回购式贴现已签收");
                    }
                } else if ("1".equals(query.detail.operType) && "12".equals(query.detail.busiType)) {//提示付款申请
                    detail.billState = "000000";    //结束已结清
                    WriteBankLogLn("由于银行没有返回票据状态：根据提示付款业务和交易成功填充票据状态【000000】提示付款申请");
                }
            }
        }
    }


    /**
     * 获取跨行付渠道，根据配置判断是否可用同城票据、网银互联、大额、小额
     *
     * @param reqPayRecDetail
     * @return
     */
    protected InterBankPayChannel getInterBankPayChannel(ReqPayRecDetail reqPayRecDetail) throws Exception {
    	InterBankPayChannel retChannel = new InterBankPayChannel();
        //1、校验isEBank是否为true,和是否跨行
        //2、如果通过银行代码、或区域名称、或银行代码+区域名称未找到对应的清算行信息，则返回false
        //3、如果eBankAmtLimit为空，且金额payAmount大于默认金额50000，则返回false
        //4、如果eBankAmtLimit不为空，则判断payAmount是否大于eBankAmtLimit，大于则返回false

        if ("0".equals(reqPayRecDetail.sameBnk)) {//跨行才需要
        	BigDecimal payAmount = new BigDecimal(reqPayRecDetail.payAmount);
        	//是否设置了启用网银互联付
            boolean setEBank = getBankConfig().getValueAsBool("isEBank");
            if(setEBank){
            	boolean hasEBankPayInfo = false;
                String[] ebankCodeRtn = EBankData.mappingEBankCode(reqPayRecDetail.recBankCode, reqPayRecDetail.recStandardArea);
                if (ebankCodeRtn != null && ebankCodeRtn[0].length() > 0) {
                	hasEBankPayInfo = true;
                	retChannel.eBankCode = ebankCodeRtn[0];
                	retChannel.eBankName = ebankCodeRtn[1];
                } else {
                    String[] ebankNameRtn = EBankData.mappingEBankCode(reqPayRecDetail.recBankName, reqPayRecDetail.recStandardArea);
                    if (ebankNameRtn != null && ebankNameRtn[0].length() > 0) {
                    	hasEBankPayInfo = true;
                    	retChannel.eBankCode = ebankCodeRtn[0];
                    	retChannel.eBankName = ebankCodeRtn[1];
                    }
                }
                if (hasEBankPayInfo) {
                	//网银互联付限额
                    String eBankAmtLimitStr = getBankConfig().getValueAsString("eBankAmtLimit");
                    BigDecimal eBankAmtLimit = null;
                    if (StringHelper.isNullOrEmpty(eBankAmtLimitStr)) {
                    	eBankAmtLimit = new BigDecimal("50000");//默认5万
                    } else {
                    	eBankAmtLimit = new BigDecimal(eBankAmtLimitStr);
                    }
                    if (payAmount.compareTo(eBankAmtLimit) <= 0) {
                    	retChannel.isEBank = true;
                    } else {
                    	retChannel.isEBank = false;
                    }
                }
            }
          
            //跨行+同城+非加急+起用了票交
            if("1".equals(reqPayRecDetail.sameCity) && getBankConfig().getValueAsBool("isPiaoJiao") && "0".equals(reqPayRecDetail.paySpd)){
            	retChannel.isPiaoJiao = true;
            }
          
            //设置了加急走大额，无论付多少金额都在大额
            if("1".equals(reqPayRecDetail.paySpd) && getBankConfig().getValueAsBool("largePayIfUrgent")){
            	retChannel.isLargeChannel = true;
            }else{
            	//小额的限额
            	String smallAmtLimitStr = getBankConfig().getValueAsString("smallAmtLimit");
                BigDecimal smallAmtLimit = null;
                if (StringHelper.isNullOrEmpty(smallAmtLimitStr)) {
                	smallAmtLimit = new BigDecimal("50000");//默认5万
                } else {
                	smallAmtLimit = new BigDecimal(smallAmtLimitStr);
                }
                if (payAmount.compareTo(smallAmtLimit) <= 0) {
                	retChannel.isLargeChannel = false;//是小额
                } else {
                	retChannel.isLargeChannel = true;//是大额
                }
            }
        }
        
        return retChannel;
    }

    public static BigDecimal getDiscAmt(ReqB106BillDiscSubmitDetail detail) throws Exception {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(Format.Date10Format.parse(detail.dueDate.substring(0, 10)));
        int diffDay = (int) Math.ceil(DateHelper.getDifferDays2(Format.Date10Format.parse(detail.dueDate.substring(0, 10)), new Date()));
        if (calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY) {
            diffDay += 2;
        } else if (calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
            diffDay += 1;
        }
        BigDecimal discAmt;
        if ("1".equals(detail.payInterestType)) {
            discAmt = new BigDecimal(detail.billAmt).
                    subtract(new BigDecimal(detail.billAmt).
                            multiply(new BigDecimal(detail.discRate)).
                            multiply(new BigDecimal(diffDay + "")).
                            divide(new BigDecimal(36000 + ""), 4, BigDecimal.ROUND_HALF_UP));
        } else if ("2".equals(detail.payInterestType)) {
            //买方付息时贴现实付金额等于票面金额
            discAmt = new BigDecimal(detail.billAmt);
        } else {
            //协议付息时，贴现实付基恩等于票面金额-卖方付息金额
            discAmt = new BigDecimal(detail.billAmt).
                    subtract(new BigDecimal(detail.billAmt).
                            multiply(new BigDecimal(detail.discRate)).
                            multiply(new BigDecimal("100.00").subtract(new BigDecimal(detail.payInterestRate))).
                            multiply(new BigDecimal(diffDay + "")).
                            divide(new BigDecimal(3600000 + ""), 4, BigDecimal.ROUND_HALF_UP));
        }
        return discAmt;
    }

    public void detailSimulateForBank(String bankCode, String transType, String commandCode, String p_reqStr, String[] retStr) {
        try {
            if (StringHelper.hasAnyChar(FGBiz.dspCenter.dspSet.bankSimulate) && ("true".equalsIgnoreCase(FGBiz.dspCenter.dspSet.bankSimulate) || FGBiz.dspCenter.dspSet.bankSimulate.contains("," + bankCode + ","))) {
                // 读取DSP后置挡板文件
                String contractSimulateFile = FGBiz.DSPHOME + File.separator + "dsp-config/SimulateForBank" + File.separator + bankCode + "_" + transType + "_" + commandCode + "_SimulateForBank.txt";
                File tmpFile = new File(contractSimulateFile);
                if (tmpFile.exists()) {
                    WriteBankLogLn("2.发送DSP后置挡板报文：\r\n" + p_reqStr);
                    String fileTxt = FileHelper.readFileText(contractSimulateFile, "utf-8");
                    retStr[1] = fileTxt;
                    WriteBankLogLn("3.读取DSP后置挡板模拟报文：" + contractSimulateFile + "\r\n" + retStr[1]);
                }
            }
        } catch (Exception e) {
            WriteBankLogLn("99.调用DSP后置挡板异常：" + e.getMessage());
        }
    }
}
